﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Security.Permissions;
using Microsoft.VisualStudio.Modeling.Design;
using System.Windows.Forms;

namespace Microsoft.Samples.DslTools.ConfigurationSectionDesigner.CustomCode
{
    public class AttributeListTypeConverter : TypeConverter
    {
        public override object ConvertTo( ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType )
        {
            if( destinationType == typeof( string ) )
                return value.ToString();

            return base.ConvertTo( context, culture, value, destinationType );
        }
    }

    public class AttributeEditor : UITypeEditor
    {
        [SecurityPermission( SecurityAction.LinkDemand )]
        public override object EditValue( ITypeDescriptorContext context, IServiceProvider provider, object value )
        {
            if( context == null )
            {
                throw new ArgumentNullException( "context" );
            }
            if( provider == null )
            {
                throw new ArgumentNullException( "provider" );
            }
            if( value == null )
            {
                throw new ArgumentNullException( "value" );
            }

            ElementPropertyDescriptor propertyDescriptor = context.PropertyDescriptor as ElementPropertyDescriptor;
            if( (propertyDescriptor != null) && ((propertyDescriptor.ModelElement is ConfigurationProperty)) )
            {
                ConfigurationProperty configElement = propertyDescriptor.ModelElement as ConfigurationProperty;
                LinkedList<Attribute> attributes = configElement.CustomAttributes;

                using( AttributesForm attributeForm = new AttributesForm( attributes ) )
                {
                    attributeForm.ShowDialog();

                    if( attributeForm.IsDirty )
                    {
                        // Trick that makes the DSL model realize we've made changes -- the return
                        // value must be different than the provided value.
                        AttributeList newList = new AttributeList();
                        foreach( Attribute attribute in configElement.CustomAttributes )
                        {
                            newList.AddLast( attribute );
                        }
                        return newList;
                    }
                }
            }

            return value;
        }

        [SecurityPermission( SecurityAction.LinkDemand )]
        public override UITypeEditorEditStyle GetEditStyle( ITypeDescriptorContext context )
        {
            return UITypeEditorEditStyle.Modal;
        }

    }

}
